<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    
    <title>Debug 小结 | jouyouyun&#39;s blog</title>
    <meta name="viewport" content="width=device-width,minimum-scale=1">
    <meta name="description" content="调试 bug 的时候要有耐心, 要不断测试, 直到找到问题原因.
基本思路
确定 bug 出现的方式

一定要找到稳定重现的方式, 这样才能方便下面的调试
如果找不到稳定重现的方法就只能根据上次出现的情形, 去查看相关的代码, 猜测可能出问题的地方, 然后针对那一块进行调试, 直到找到稳定重现方式

定位出问题的代码

再找到稳定重现方式后, 开始定位出问题的函数, 然后加入调试信息, 不断尝试, 直到找到有问题的代码
找到有问题的代码后, 如果发现是第三方库里的函数,可以打印出每次调用的输入输出参数, 看看是否有迹可循, 可以单独写个小程序, 传入问题的参数, 进行不断测试, 来确定第三方库有没有问题
如果自己程序的代码, 就一行一行的慢慢测试, 确定问题的原因, 原因找到了就可以开始思考解决方法了
">
    <meta name="generator" content="Hugo 0.105.0">
    
    
    
    
      <meta name="robots" content="noindex, nofollow">
    

    
<link rel="stylesheet" href="/ananke/css/main.min.css" >



    
    
    
      

    

    
    
    <meta property="og:title" content="Debug 小结" />
<meta property="og:description" content="调试 bug 的时候要有耐心, 要不断测试, 直到找到问题原因.
基本思路
确定 bug 出现的方式

一定要找到稳定重现的方式, 这样才能方便下面的调试
如果找不到稳定重现的方法就只能根据上次出现的情形, 去查看相关的代码, 猜测可能出问题的地方, 然后针对那一块进行调试, 直到找到稳定重现方式

定位出问题的代码

再找到稳定重现方式后, 开始定位出问题的函数, 然后加入调试信息, 不断尝试, 直到找到有问题的代码
找到有问题的代码后, 如果发现是第三方库里的函数,可以打印出每次调用的输入输出参数, 看看是否有迹可循, 可以单独写个小程序, 传入问题的参数, 进行不断测试, 来确定第三方库有没有问题
如果自己程序的代码, 就一行一行的慢慢测试, 确定问题的原因, 原因找到了就可以开始思考解决方法了
" />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://jouyouyun.github.io/post/debug-summary/" /><meta property="article:section" content="post" />
<meta property="article:published_time" content="2016-02-03T15:06:21+08:00" />
<meta property="article:modified_time" content="2019-05-12T22:22:49+08:00" />

<meta itemprop="name" content="Debug 小结">
<meta itemprop="description" content="调试 bug 的时候要有耐心, 要不断测试, 直到找到问题原因.
基本思路
确定 bug 出现的方式

一定要找到稳定重现的方式, 这样才能方便下面的调试
如果找不到稳定重现的方法就只能根据上次出现的情形, 去查看相关的代码, 猜测可能出问题的地方, 然后针对那一块进行调试, 直到找到稳定重现方式

定位出问题的代码

再找到稳定重现方式后, 开始定位出问题的函数, 然后加入调试信息, 不断尝试, 直到找到有问题的代码
找到有问题的代码后, 如果发现是第三方库里的函数,可以打印出每次调用的输入输出参数, 看看是否有迹可循, 可以单独写个小程序, 传入问题的参数, 进行不断测试, 来确定第三方库有没有问题
如果自己程序的代码, 就一行一行的慢慢测试, 确定问题的原因, 原因找到了就可以开始思考解决方法了
"><meta itemprop="datePublished" content="2016-02-03T15:06:21+08:00" />
<meta itemprop="dateModified" content="2019-05-12T22:22:49+08:00" />
<meta itemprop="wordCount" content="184">
<meta itemprop="keywords" content="debug,perf,pprof,gdb,sar,performance," /><meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="Debug 小结"/>
<meta name="twitter:description" content="调试 bug 的时候要有耐心, 要不断测试, 直到找到问题原因.
基本思路
确定 bug 出现的方式

一定要找到稳定重现的方式, 这样才能方便下面的调试
如果找不到稳定重现的方法就只能根据上次出现的情形, 去查看相关的代码, 猜测可能出问题的地方, 然后针对那一块进行调试, 直到找到稳定重现方式

定位出问题的代码

再找到稳定重现方式后, 开始定位出问题的函数, 然后加入调试信息, 不断尝试, 直到找到有问题的代码
找到有问题的代码后, 如果发现是第三方库里的函数,可以打印出每次调用的输入输出参数, 看看是否有迹可循, 可以单独写个小程序, 传入问题的参数, 进行不断测试, 来确定第三方库有没有问题
如果自己程序的代码, 就一行一行的慢慢测试, 确定问题的原因, 原因找到了就可以开始思考解决方法了
"/>

	
  </head>

  <body class="ma0 avenir bg-near-white">

    
   
  

  <header>
    <div class="bg-black">
      <nav class="pv3 ph3 ph4-ns" role="navigation">
  <div class="flex-l justify-between items-center center">
    <a href="/" class="f3 fw2 hover-white no-underline white-90 dib">
      
        jouyouyun&#39;s blog
      
    </a>
    <div class="flex-l items-center">
      

      
        <ul class="pl0 mr3">
          
          <li class="list f5 f4-ns fw4 dib pr3">
            <a class="hover-white no-underline white-90" href="/post/" title="Archives 页">
              Archives
            </a>
          </li>
          
          <li class="list f5 f4-ns fw4 dib pr3">
            <a class="hover-white no-underline white-90" href="/tags/" title="Tags 页">
              Tags
            </a>
          </li>
          
          <li class="list f5 f4-ns fw4 dib pr3">
            <a class="hover-white no-underline white-90" href="/categories/" title="Categories 页">
              Categories
            </a>
          </li>
          
        </ul>
      
      
<div class="ananke-socials">
  
    <a href="https://github.com/jouyouyun" target="_blank" class="github ananke-social-link link-transition stackoverflow link dib z-999 pt3 pt0-l mr1" title="GitHub link" rel="noopener" aria-label="follow on GitHub——Opens in a new window">
      
        <span class="icon"><svg style="enable-background:new 0 0 512 512;" version="1.1" viewBox="0 0 512 512"  xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >
  <path d="M256,32C132.3,32,32,134.8,32,261.7c0,101.5,64.2,187.5,153.2,217.9c11.2,2.1,15.3-5,15.3-11.1   c0-5.5-0.2-19.9-0.3-39.1c-62.3,13.9-75.5-30.8-75.5-30.8c-10.2-26.5-24.9-33.6-24.9-33.6c-20.3-14.3,1.5-14,1.5-14   c22.5,1.6,34.3,23.7,34.3,23.7c20,35.1,52.4,25,65.2,19.1c2-14.8,7.8-25,14.2-30.7c-49.7-5.8-102-25.5-102-113.5   c0-25.1,8.7-45.6,23-61.6c-2.3-5.8-10-29.2,2.2-60.8c0,0,18.8-6.2,61.6,23.5c17.9-5.1,37-7.6,56.1-7.7c19,0.1,38.2,2.6,56.1,7.7   c42.8-29.7,61.5-23.5,61.5-23.5c12.2,31.6,4.5,55,2.2,60.8c14.3,16.1,23,36.6,23,61.6c0,88.2-52.4,107.6-102.3,113.3   c8,7.1,15.2,21.1,15.2,42.5c0,30.7-0.3,55.5-0.3,63c0,6.1,4,13.3,15.4,11C415.9,449.1,480,363.1,480,261.7   C480,134.8,379.7,32,256,32z"/>
</svg>
</span>
      
<span class="new-window"><svg  height="8px"  style="enable-background:new 0 0 1000 1000;" version="1.1" viewBox="0 0 1000 1000"  xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >
<path d="M598 128h298v298h-86v-152l-418 418-60-60 418-418h-152v-86zM810 810v-298h86v298c0 46-40 86-86 86h-596c-48 0-86-40-86-86v-596c0-46 38-86 86-86h298v86h-298v596h596z" style="fill-rule:evenodd;clip-rule:evenodd;"/>
</svg>
</span></a>
  
</div>

    </div>
  </div>
</nav>

    </div>
  </header>



    <main class="pb7" role="main">
      
  
  <article class="flex-l flex-wrap justify-between mw8 center ph3">
    <header class="mt4 w-100">
      <aside class="instapaper_ignoref b helvetica tracked">
          
        POSTS
      </aside>
      










  <div id="sharing" class="mt3 ananke-socials">
    
  </div>


      <h1 class="f1 athelas mt3 mb1">Debug 小结</h1>
      
      <p class="tracked">
         <strong>jouyouyun</strong>
      </p>
      
      
      
      <time class="f6 mv4 dib tracked" datetime="2016-02-03T15:06:21+08:00">二月 3, 2016</time>
      

      
      
    </header>
    <div class="nested-copy-line-height lh-copy serif f4 nested-links mid-gray pr4-l w-two-thirds-l"><p>调试 <code>bug</code> 的时候要有耐心, 要不断测试, 直到找到问题原因.</p>
<h2 id="基本思路">基本思路</h2>
<h3 id="确定-bug-出现的方式">确定 <code>bug</code> 出现的方式</h3>
<ul>
<li>一定要找到稳定重现的方式, 这样才能方便下面的调试</li>
<li>如果找不到稳定重现的方法就只能根据上次出现的情形, 去查看相关的代码, 猜测可能出问题的地方, 然后针对那一块进行调试, 直到找到稳定重现方式</li>
</ul>
<h3 id="定位出问题的代码">定位出问题的代码</h3>
<ul>
<li>再找到稳定重现方式后, 开始定位出问题的函数, 然后加入调试信息, 不断尝试, 直到找到有问题的代码</li>
<li>找到有问题的代码后, 如果发现是第三方库里的函数,可以打印出每次调用的输入输出参数, 看看是否有迹可循, 可以单独写个小程序, 传入问题的参数, 进行不断测试, 来确定第三方库有没有问题</li>
<li>如果自己程序的代码, 就一行一行的慢慢测试, 确定问题的原因, 原因找到了就可以开始思考解决方法了</li>
</ul>
<h3 id="修复-bug">修复 <code>bug</code></h3>
<p>修复 <code>bug</code> 时一定要仔细检查新添加的代码, 看看会不会造成其它的 <code>bug</code>, 一定要不断测试, 把函数输入输出状态都打印出来, 以免出现界面是对的, 但函数的数据有误.</p>
<p>对于开源的第三方库有问题时, 就把它的代码下下来, 加上调试信息后, 然后安装, 让你的程序使用自己编译的第三方库, 这样方便查找问题.
因为有时可能第三方库再使用时需要初始化一些资源, 而你使用的接口并没有做或少做了一点, 这样就导致你的程序出了问题.
这时就可以在程序中添加相关的初始化代码, 来处理这类问题, 这类问题一般第三方库升级时可能出现.</p>
<p>若知道问题的原因后(这个原因一定要是相关低层的, 不能说是由于 A 调了 B , B 出问题了, 就把问题原因归与 A 的头上, 一定要是相当精确的), 不知道怎么修改, 这时就可以向组内成员求助, 或者去了解这方面的知识.</p>
<h3 id="使用性能调试工具">使用性能调试工具</h3>
<p>在代码中添加 <code>pprof</code> 支持，通过环境变量或指定参数等方法来启用。</p>
<p>对于 <code>C/C++</code> 代码, 可以使用 <code>Google Proftools</code> 工具来调试，而 <code>go</code> 则内置了 <code>pprof</code> 的支持. <code>pprof</code> 以程序调用的方式生成每次调用的性能消耗图, 方便定位占用资源多的函数.</p>
<p>文档见: <a href="http://google-perftools.googlecode.com/svn/trunk/doc/">Google Proftools Documents</a> , 使用方法自行 <code>google</code> .</p>
<p><code>go</code> 中 <code>runtime/pprof</code> 和 <code>net/http/pprof</code> 均提供了 <code>pprof</code> 支持，后者启用后提供了 <code>http</code> 接口，文档分别参见： <a href="https://godoc.org/runtime/pprof">runtime/pprof</a> 和 <a href="https://godoc.org/net/http/pprof">net/http/pprof</a></p>
<h3 id="查找资料">查找资料</h3>
<p>还可以去一些开发者网站提问:</p>
<ul>
<li><a href="http://stackoverflow.com/">StackOverflow</a></li>
<li><a href="https://www.quora.com/">国外的知乎: Quora</a></li>
<li><a href="http://segmentfault.com/">SegmentFault</a></li>
</ul>
<p>或者到 <a href="http://www.ibm.com/developerworks/cn/">IBM Developer</a> 看写相关的技术文章, 前端的话还可以去 <a href="https://developer.mozilla.org/">Mozilla Developer</a> .</p>
<h2 id="调试方法">调试方法</h2>
<p>这里分别列出笔者常用的几种调试方法，并给出用到的场景。</p>
<p>(<strong>注：在调试前安装好需要的 <code>dbg</code> 包</strong>)</p>
<h3 id="添加打印信息">添加打印信息</h3>
<p>使用这种方法的前提是拥有源码，并已经可以确定出现 <code>bug</code> 的范围，然后对产生 <code>bug</code> 的代码添加有意义的打印信息。</p>
<h3 id="使用-gdb">使用 <code>gdb</code></h3>
<p><code>gdb</code> 的适用范围就很广了，如程序异常终止，资源使用异常等。但使用之前需要学习如何使用，这里推荐： <a href="http://blog.jobbole.com/107759/">gdb 调试入门，大牛写的高质量指南</a> 。</p>
<p>另外建议启用 <code>coredump</code> ，这将会在程序崩溃时保留当时的调用栈信息，启用方法参见之前的文章： <a href="http://jouyouyun.github.io/post/enable-coredump/">Enable Coredump</a> 。</p>
<h3 id="使用-pprof">使用 <code>pprof</code></h3>
<p><code>pprof</code> 上文中已经有过介绍，主要用于性能调优，通常在程序资源占用异常时使用，如 <code>cpu 100%</code> 或 =内存泄漏=。</p>
<p>但使用时需要修改代码。</p>
<h3 id="使用-perf">使用 <code>perf</code></h3>
<p><code>perf</code> 与 <code>pprof</code> 类似，但它不需要修改代码。使用方法见：</p>
<ul>
<li><a href="https://docs-blog.wh-redirect.deepin.cn/?p=735">使用 Perf 优化程序性能 </a></li>
<li><a href="https://www.ibm.com/developerworks/cn/linux/l-cn-perf1/index.html">Perf &ndash; Linux下的系统性能调优工具</a></li>
</ul>
<h3 id="分析-proc-syscall">分析 <code>proc syscall</code></h3>
<p>主要是通过分析进程及其线程的调用栈，找到出问题的线程，然后查看其内存数据来确定问题，参见：<a href="https://docs-blog.wh-redirect.deepin.cn/?p=794#i-2">记一次SPECjvm2008问题排查</a></p>
<h2 id="性能优化">性能优化</h2>
<ul>
<li><a href="http://www.brendangregg.com/Perf/linux%5Fobservability%5Ftools.png">Linux 性能观测工具</a></li>
<li><a href="http://www.brendangregg.com/Perf/linux%5Fbenchmarking%5Ftools.png">Linux 性能测评工具</a></li>
<li><a href="http://www.brendangregg.com/Perf/linux%5Ftuning%5Ftools.png">Linux 性能调优工具</a></li>
<li><a href="http://www.brendangregg.com/Perf/linux%5Fobservability%5Fsar">sar</a></li>
</ul>
<p>更多工具参加：<a href="http://www.brendangregg.com/linuxperf.html">Linux Performance</a> 。</p><ul class="pa0">
  
   <li class="list di">
     <a href="/tags/debug" class="link f5 grow no-underline br-pill ba ph3 pv2 mb2 dib black sans-serif">debug</a>
   </li>
  
   <li class="list di">
     <a href="/tags/perf" class="link f5 grow no-underline br-pill ba ph3 pv2 mb2 dib black sans-serif">perf</a>
   </li>
  
   <li class="list di">
     <a href="/tags/pprof" class="link f5 grow no-underline br-pill ba ph3 pv2 mb2 dib black sans-serif">pprof</a>
   </li>
  
   <li class="list di">
     <a href="/tags/gdb" class="link f5 grow no-underline br-pill ba ph3 pv2 mb2 dib black sans-serif">gdb</a>
   </li>
  
   <li class="list di">
     <a href="/tags/sar" class="link f5 grow no-underline br-pill ba ph3 pv2 mb2 dib black sans-serif">sar</a>
   </li>
  
   <li class="list di">
     <a href="/tags/performance" class="link f5 grow no-underline br-pill ba ph3 pv2 mb2 dib black sans-serif">performance</a>
   </li>
  
</ul>
<div class="mt6 instapaper_ignoref">
      
      
      </div>
    </div>

    <aside class="w-30-l mt6-l">




</aside>

  </article>

    </main>
    <footer class="bg-black bottom-0 w-100 pa3" role="contentinfo">
  <div class="flex justify-between">
  <a class="f4 fw4 hover-white no-underline white-70 dn dib-ns pv2 ph3" href="https://jouyouyun.github.io" >
    &copy;  jouyouyun 2023 
  </a>
    <div>
<div class="ananke-socials">
  
    <a href="https://github.com/jouyouyun" target="_blank" class="github ananke-social-link link-transition stackoverflow link dib z-999 pt3 pt0-l mr1" title="GitHub link" rel="noopener" aria-label="follow on GitHub——Opens in a new window">
      
        <span class="icon"><svg style="enable-background:new 0 0 512 512;" version="1.1" viewBox="0 0 512 512"  xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >
  <path d="M256,32C132.3,32,32,134.8,32,261.7c0,101.5,64.2,187.5,153.2,217.9c11.2,2.1,15.3-5,15.3-11.1   c0-5.5-0.2-19.9-0.3-39.1c-62.3,13.9-75.5-30.8-75.5-30.8c-10.2-26.5-24.9-33.6-24.9-33.6c-20.3-14.3,1.5-14,1.5-14   c22.5,1.6,34.3,23.7,34.3,23.7c20,35.1,52.4,25,65.2,19.1c2-14.8,7.8-25,14.2-30.7c-49.7-5.8-102-25.5-102-113.5   c0-25.1,8.7-45.6,23-61.6c-2.3-5.8-10-29.2,2.2-60.8c0,0,18.8-6.2,61.6,23.5c17.9-5.1,37-7.6,56.1-7.7c19,0.1,38.2,2.6,56.1,7.7   c42.8-29.7,61.5-23.5,61.5-23.5c12.2,31.6,4.5,55,2.2,60.8c14.3,16.1,23,36.6,23,61.6c0,88.2-52.4,107.6-102.3,113.3   c8,7.1,15.2,21.1,15.2,42.5c0,30.7-0.3,55.5-0.3,63c0,6.1,4,13.3,15.4,11C415.9,449.1,480,363.1,480,261.7   C480,134.8,379.7,32,256,32z"/>
</svg>
</span>
      
<span class="new-window"><svg  height="8px"  style="enable-background:new 0 0 1000 1000;" version="1.1" viewBox="0 0 1000 1000"  xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >
<path d="M598 128h298v298h-86v-152l-418 418-60-60 418-418h-152v-86zM810 810v-298h86v298c0 46-40 86-86 86h-596c-48 0-86-40-86-86v-596c0-46 38-86 86-86h298v86h-298v596h596z" style="fill-rule:evenodd;clip-rule:evenodd;"/>
</svg>
</span></a>
  
</div>
</div>
  </div>
</footer>

  </body>
</html>
